﻿/* 
 * 可勾选treeview树形视图
 */
(function ($) {
    $.fn.treeview_check = function (option) {
        /// <summary>
        /// 可勾选树形视图,基于bootstrap-treeview控件，选中一个节点会联动选择所有子节点和当前节点的所有上级节点
        /// </summary>
        /// <param name="option">配置项:<br/>
        /// 背景色选中不可多选<br/>
        /// levels:默认展开级别，默认为2;<br/>
        /// data:绑定数据;<br/>
        /// 其他参数请参考bootstrap-treeview介绍：http://www.htmleaf.com/jQuery/Menu-Navigation/201502141379.html ;<br/>
        /// </param>
        var opt = {
            showTags: true,
            multiSelect: false,
            showCheckbox: true,
            onNodeChecked: function (event, node) {
                if (!$.fn.treeview_check.nodes[node.nodeId]) {
                    $.fn.treeview_check.nodes[node.nodeId] = node;
                }
                checkParent(node);//上级联动
                checkSun(node);//下级联动
            },
            onNodeUnchecked: function (event, node) {
                if ($.fn.treeview_check.nodes[node.nodeId]) {
                    $.fn.treeview_check.nodes[node.nodeId] = null;
                }
                checkParent(node);//上级联动
                checkSun(node);//下级联动
            }
        }
        $.extend(opt, option);
        var $tree = $(this).treeview(opt);
        //上级联动
        function checkParent(node) {
            if (node.parentId != undefined) {
                var checked = 0;
                var part = false;
                var pnode = $tree.treeview('getParent', node);
                for (var i = 0; i < pnode.nodes.length; i++) {
                    if (pnode.nodes[i].checkedIcon == "glyphicon glyphicon-stop") {
                        part = true;
                        break;
                    }
                    if (pnode.nodes[i].state.checked) {
                        checked++;
                    }
                }
                if (part) {
                    pnode.checkedIcon = "glyphicon glyphicon-stop";
                    $tree.treeview('checkNode', [pnode, { silent: true }]);
                } else {
                    if (checked >= pnode.nodes.length) {
                        pnode.checkedIcon = null;
                        $tree.treeview('checkNode', [pnode, { silent: true }]);
                    } else if (checked <= 0) {
                        pnode.checkedIcon = null;
                        $tree.treeview('uncheckNode', [pnode, { silent: true }]);
                    } else {
                        pnode.checkedIcon = "glyphicon glyphicon-stop";
                        $tree.treeview('checkNode', [pnode, { silent: true }]);
                    }
                }
                if (checked<=0) {
                    if ($.fn.treeview_check.nodes[pnode.nodeId]) {
                        $.fn.treeview_check.nodes[pnode.nodeId] = null;
                    }
                } else { 
                    if (!$.fn.treeview_check.nodes[pnode.nodeId]) {
                        $.fn.treeview_check.nodes[pnode.nodeId] = pnode;
                    }
                }
                checkParent(pnode);
            }
        }
        //下级联动
        function checkSun(node) {
            var statestr = "uncheckNode";
            if (node.state.checked) {
                var statestr = "checkNode";
            }
            if (node.nodes && node.nodes.length > 0) {
                for (var i = 0; i < node.nodes.length; i++) {
                    $tree.treeview(statestr, node.nodes[i].nodeId, { silent: true });
                    if (statestr == "uncheckNode") {
                        if ($.fn.treeview_check.nodes[node.nodes[i].nodeId]) {
                            $.fn.treeview_check.nodes[node.nodes[i].nodeId] = null;
                        }
                    } else {
                        if ($.fn.treeview_check.nodes[node.nodes[i].nodeId]) {
                            $.fn.treeview_check.nodes[node.nodes[i].nodeId] = node.nodes[i];
                        }
                    }
                }
            }
        }
    }
    //勾选的节点数据集合
    $.fn.treeview_check.nodes = [];
    $.fn.treeview_check.getChecked = function () {
        /// <summary>
        /// 返回选中的节点
        /// </summary>
        var result = [];
        for (var i = 0; i < $.fn.treeview_check.nodes.length; i++) {
            if ($.fn.treeview_check.nodes[i]) {
                result.push($.fn.treeview_check.nodes[i]);
            }
        }
        return result;
    }
    $.fn.treeview_check.nodes_data = [];
    $.fn.treeview_check.getNodeData = function (node, level,check) {
        /// <summary>
        /// 将数据转换成treeview的node数据形式
        /// </summary>
        /// <param name="node">含有nodes的tree数据对象</param>
        /// <param name="level">当前级别，根为0</param>
        if (!node.nodes) return;
        level += 1;

        var parent = node;
        $.each(node.nodes, function checkStates(index, node) {

            // nodeId : unique, incremental identifier
            node.nodeId = $.fn.treeview_check.nodes_data.length;

            // parentId : transversing up the tree
            node.parentId = parent.nodeId;

            // if not provided set selectable default value
            if (!node.hasOwnProperty('selectable')) {
                node.selectable = true;
            }

            // where provided we should preserve states
            node.state = node.state || {};

            // set checked state; unless set always false
            if (!node.state.hasOwnProperty('checked')) {
                node.state.checked = false;
            }

            // set enabled state; unless set always false
            if (!node.state.hasOwnProperty('disabled')) {
                node.state.disabled = false;
            }

            // set expanded state; if not provided based on levels
            if (!node.state.hasOwnProperty('expanded')) {
                if (!node.state.disabled &&
						//(level < _this.options.levels) &&
						(node.nodes && node.nodes.length > 0)) {
                    node.state.expanded = true;
                }
                else {
                    node.state.expanded = false;
                }
            }

            // set selected state; unless set always false
            if (!node.state.hasOwnProperty('selected')) {
                node.state.selected = false;
            }

            // index nodes in a flattened structure for use later
            $.fn.treeview_check.nodes_data.push(node);

            // recurse child nodes and transverse the tree
            if (node.nodes) {
                $.fn.treeview_check.setNode(node, level);
            }
            if ($.inArray(node.id, check)) {

            }
        });
    };
})(jQuery);